From: Carlos Soriano Date: Tue, 17 Jun 2014 19:31:53 +0000 (+0200) Subject: appDisplay: Animate appIcon for new window of apps X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~2206 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=62786c09a894de2bb4154d1ef683cb0d68f6704b;p=gnome-shell.git appDisplay: Animate appIcon for new window of apps Following design mockups, animate the icons on AllView, FrequentView, Dash and Search to zoom out when opening a new window of the app or when the app is not running and the user execute it. https://bugzilla.gnome.org/show_bug.cgi?id=734726 --- diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index 32ffd10a8..24d386dd7 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -1699,6 +1699,9 @@ const AppIcon = new Lang.Class({ this.app.state == Shell.AppState.RUNNING || button && button == 2; + if (this.app.state == Shell.AppState.STOPPED || openNewWindow) + this.animateLaunch(); + if (openNewWindow) this.app.open_new_window(-1); else @@ -1707,6 +1710,10 @@ const AppIcon = new Lang.Class({ Main.overview.hide(); }, + animateLaunch: function() { + this.icon.animateZoomOut(); + }, + shellWorkspaceLaunch : function(params) { params = Params.parse(params, { workspace: -1, timestamp: 0 }); @@ -1788,6 +1795,9 @@ const AppIconMenu = new Lang.Class({ if (this._source.app.can_open_new_window()) { this._newWindowMenuItem = this._appendMenuItem(_("New Window")); this._newWindowMenuItem.connect('activate', Lang.bind(this, function() { + if (this._source.app.state == Shell.AppState.STOPPED) + this._source.animateLaunch(); + this._source.app.open_new_window(-1); this.emit('activate-window', null); })); diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js index 31d4ea309..f00b22f17 100644 --- a/js/ui/iconGrid.js +++ b/js/ui/iconGrid.js @@ -30,6 +30,9 @@ const AnimationDirection = { OUT: 1 }; +const APPICON_ANIMATION_OUT_SCALE = 3; +const APPICON_ANIMATION_OUT_TIME = 0.25; + const BaseIcon = new Lang.Class({ Name: 'BaseIcon', @@ -187,9 +190,55 @@ const BaseIcon = new Lang.Class({ _onIconThemeChanged: function() { this._createIconTexture(this.iconSize); + }, + + animateZoomOut: function() { + // Animate only the child instead of the entire actor, so the + // styles like hover and running are not applied while + // animating. + zoomOutActor(this.actor.child); } }); +function clamp(value, min, max) { + return Math.max(Math.min(value, max), min); +}; + +function zoomOutActor(actor) { + let actorClone = new Clutter.Clone({ source: actor, + reactive: false }); + let [width, height] = actor.get_transformed_size(); + let [x, y] = actor.get_transformed_position(); + actorClone.set_size(width, height); + actorClone.set_position(x, y); + actorClone.opacity = 255; + actorClone.set_pivot_point(0.5, 0.5); + + Main.uiGroup.add_actor(actorClone); + + // Avoid monitor edges to not zoom outside the current monitor + let monitor = Main.layoutManager.findMonitorForActor(actor); + let scaledWidth = width * APPICON_ANIMATION_OUT_SCALE; + let scaledHeight = height * APPICON_ANIMATION_OUT_SCALE; + let scaledX = x - (scaledWidth - width) / 2; + let scaledY = y - (scaledHeight - height) / 2; + let containedX = clamp(scaledX, monitor.x, monitor.x + monitor.width - scaledWidth); + let containedY = clamp(scaledY, monitor.y, monitor.y + monitor.height - scaledHeight); + + Tweener.addTween(actorClone, + { time: APPICON_ANIMATION_OUT_TIME, + scale_x: APPICON_ANIMATION_OUT_SCALE, + scale_y: APPICON_ANIMATION_OUT_SCALE, + translation_x: containedX - scaledX, + translation_y: containedY - scaledY, + opacity: 0, + transition: 'easeOutQuad', + onComplete: function() { + actorClone.destroy(); + } + }); +} + const IconGrid = new Lang.Class({ Name: 'IconGrid', diff --git a/js/ui/search.js b/js/ui/search.js index 583792702..3278c8f79 100644 --- a/js/ui/search.js +++ b/js/ui/search.js @@ -6,6 +6,7 @@ const Gio = imports.gi.Gio; const Gtk = imports.gi.Gtk; const Meta = imports.gi.Meta; const Signals = imports.signals; +const Shell = imports.gi.Shell; const St = imports.gi.St; const Atk = imports.gi.Atk; @@ -397,6 +398,7 @@ const ListSearchResults = new Lang.Class({ this.providerIcon.connect('key-focus-in', Lang.bind(this, this._keyFocusIn)); this.providerIcon.connect('clicked', Lang.bind(this, function() { + this.providerIcon.animateLaunch(); provider.launchSearch(this._terms); Main.overview.toggle(); })); @@ -708,5 +710,12 @@ const ProviderIcon = new Lang.Class({ gicon: provider.appInfo.get_icon() }); this._content.add_actor(icon); this._content.add_actor(this.moreIcon); + }, + + animateLaunch: function() { + let appSys = Shell.AppSystem.get_default(); + let app = appSys.lookup_app(this.provider.appInfo.get_id()); + if (app.state == Shell.AppState.STOPPED) + IconGrid.zoomOutActor(this._content); } });